package ru.bragnikita.utils.swing.widget.form;

import com.google.common.base.Objects;
import com.google.common.collect.*;
import org.apache.commons.lang3.ObjectUtils;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Predicates.instanceOf;

/**
 * @author Nikita.Brazhnikov
 */
public class ValuesMap implements ListMultimap<String, Object> {

	private ListMultimap<String, Object> map = LinkedListMultimap.create();

	public ValuesMap() {
		super();
	}

	public String getString(String key) {
		Object val = getFirst(key);
		return ObjectUtils.toString(val, null);
	}

	@SuppressWarnings("unchecked")
	public <T> T getValueOfType(String key, Class<T> valueType) {
		List<Object> values = get(key);
		return (T) Iterables.find(values, instanceOf(valueType), null);
	}

	public Object getFirst(String key) {
		return Iterables.getFirst(get(key), null);
	}

	@Override
	public int size() {
		return map.size();
	}

	@Override
	public boolean isEmpty() {
		return map.isEmpty();
	}

	@Override
	public boolean containsKey(@Nullable Object key) {
		return map.containsKey(key);
	}

	@Override
	public boolean containsValue(@Nullable Object value) {
		return map.containsValue(value);
	}

	@Override
	public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
		return map.containsEntry(key,value);
	}

	@Override
	public boolean put(@Nullable String key, @Nullable Object value) {
		return map.put(key,value);
	}

	@Override
	public boolean remove(@Nullable Object key, @Nullable Object value) {
		return map.remove(key,value);
	}

	@Override
	public boolean putAll(@Nullable String key, Iterable<?> values) {
		return map.putAll(key,values);
	}

	@Override
	public boolean putAll(Multimap<? extends String, ?> multimap) {
		return map.putAll(multimap);
	}

	@Override
	public List<Object> replaceValues(@Nullable String key, Iterable<?> values) {
		return map.replaceValues(key,values);
	}

	@Override
	public List<Object> removeAll(@Nullable Object key) {
		return map.removeAll(key);
	}

	@Override
	public void clear() {
		map.clear();
	}

	@Override
	public List<Object> get(@Nullable String key) {
		return map.get(key);
	}

	@Override
	public Set<String> keySet() {
		return map.keySet();
	}

	@Override
	public Multiset<String> keys() {
		return map.keys();
	}

	@Override
	public Collection<Object> values() {
		return map.values();
	}

	@Override
	public Collection<Map.Entry<String, Object>> entries() {
		return map.entries();
	}

	@Override
	public Map<String, Collection<Object>> asMap() {
		return map.asMap();
	}

	@Override
	public String toString() {
		return Objects.toStringHelper(this)
		              .add("map", map)
		              .toString();
	}
}
